#include "ctlProcess.hpp"

/*
    使用匿名管道，完成父子进程之间的通信
    int pipe(int fildes[2]);
    fildes：输出输出型参数，返回匿名管道的两端
        fildes[0]：读端，filedes[1]：写端
    返回值：
        返回-1则失败

*/

// 检测管道的对应的文件描述符
// 当一个进程创建多个匿名管道时，查看读端和写端
void test()
{
    for(int i = 0; i < 3; i++)
    {
        int fds[2];
        if(pipe(fds) == -1)
        {
            cout << "创建管道失败" << endl;
            exit(-1);        
        }
        cout << i << " fds[0] = " << fds[0] << " fds[1] = " << fds[1] << endl;
        // 0 fds[0] = 3 fds[1] = 4
        // 1 fds[0] = 5 fds[1] = 6
        // 2 fds[0] = 7 fds[1] = 8
    }
}

// 查看多进程下的管道情况
// 让父进程是写端，子进程是读端
void test_more_process()
{
    // 记录父进程的写端，让子进程关闭。
    // 保证管道是一对一，而不是一对多
    vector<int> parent_write_fds; 
    for(int i = 0; i < 3; i++ )
    {
        int fds[2];
        if(pipe(fds) == -1)
        {
            cout << "创建管道失败" << endl;
            exit(-1);
        }
        int pid = fork();
        // 子进程
        if(pid == 0)
        {
            // error 没有关闭父进程的写端

            // 关闭父进程所有写端
            for(auto& fd : parent_write_fds)
                close(fd);
            // 关闭写端
            // 下面说法错误！！！ 是因为进程的独立性，它不是线程
            // // 为什么还要这个？ 你不能保证父进程先被调度，把当前匿名管道的写端放入parent_write_fds中
            // // 所以必须这样关闭
            // 这是因为进程的独立性

            close(fds[1]);
            exit(0);
        }

        // 父进程
        // 关闭读端
        close(fds[0]);
        // 随着循环次数增多，继承关系下，子进程会拥有父进程曾经打开的所有写端
        // 我们需要把写端记录下来让子进程关闭，保证匿名管道是一对一
        parent_write_fds.push_back(fds[1]);
    }
    
}




int main()
{
    CtlProcess ctl;
    ctl.CreateModel();
    ctl.Centre();
    ctl.WaitChild();
    return 0;
}